// yfs client.  implements FS operations using extent and lock server
#include "yfs_client.h"
#include "extent_client.h"
#include "extent_server.h"
#include <sstream>
#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


yfs_client::yfs_client(std::string extent_dst, std::string lock_dst)
{
  ec = new extent_client(extent_dst);

}

yfs_client::inum
yfs_client::n2i(std::string n)
{
  std::istringstream ist(n);
  unsigned long long finum;
  ist >> finum;
  return finum;
}

std::string
yfs_client::filename(inum inum)
{
  std::ostringstream ost;
  ost << inum;
  return ost.str();
}

bool
yfs_client::isfile(inum inum)
{
  if(inum & 0x80000000)
    return true;
  return false;
}

bool
yfs_client::isdir(inum inum)
{
  return ! isfile(inum);
}

int
yfs_client::getfile(inum inum, fileinfo &fin)
{
  int r = OK;


  printf("getfile %016llx\n", inum);
  extent_protocol::attr a;
  if (ec->getattr(inum, a) != extent_protocol::OK) {
    r = IOERR;
    goto release;
  }

  fin.atime = a.atime;
  fin.mtime = a.mtime;
  fin.ctime = a.ctime;
  fin.size = a.size;
  printf("getfile %016llx -> sz %llu\n", inum, fin.size);

 release:

  return r;
}

int
yfs_client::getdir(inum inum, dirinfo &din)
{
  int r = OK;


  printf("getdir %016llx\n", inum);
  extent_protocol::attr a;
  if (ec->getattr(inum, a) != extent_protocol::OK) {
    r = IOERR;
    goto release;
  }
  din.atime = a.atime;
  din.mtime = a.mtime;
  din.ctime = a.ctime;

 release:
  return r;
}

int yfs_client::put(inum parent, inum id, std::string buf, fileinfo &info){
  std::string contents;
  extent_protocol::attr a;

  // retreive current contents
  ec->get(parent, contents);

  // check if it is a file
  if(!isfile(id)){
    return IOERR;
  }

  // check if file is already in directory
  if(contents.find(buf) != std::string::npos){
    return IOERR;
  }

  
  // add file to directory
  char* buffer;
  sprintf(buffer, "%s %s ", buf.c_str(), filename(id).c_str());
  contents.append(std::string(buffer));
  ec->put(parent, contents);
  ec->put(id, "");

  info.atime = a.atime;
  info.ctime = a.ctime;
  info.mtime = a.mtime;
  info.size = a.size;

  return OK;
  
}

int yfs_client::get(inum id, std::string &buf){
  if(ec->get(id, buf) == extent_protocol::OK)
    return OK;
  else
    return NOENT;
}

int yfs_client::getattr(inum id, extent_protocol::attr &a){
  if(ec->getattr(id, a) == extent_protocol::OK)
    return OK;
  else
    return NOENT;
}

int yfs_client::remove(inum id){
  if(ec->remove(id) == extent_protocol::OK)
    return OK;
  else
    return NOENT;
}

